/*
 *  Copyright 2012.
 * 
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */

package org.opu.queryhandler.n.client.ui.widgets;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.border.TitledBorder;
import org.opu.queryhandler.n.client.services.DriverService;
import org.opu.queryhandler.n.client.services.beans.DriverDefenition;
import org.opu.queryhandler.n.client.ui.i18n.ConnectionDialogI18n;
import org.opu.queryhandler.n.util.GUIUtils;
import org.opu.queryhandler.n.util.ResourceHandle;
import org.opu.queryhandler.n.util.ResourceHandle.IconType;

/**
 *
 */
public final class ConnectionDialog extends JDialog {

    private ConnectionDialogI18n i18n = new ConnectionDialogI18n();

    private JTextField url = GUIUtils.addActions(new JTextField());
    private JTextField user = GUIUtils.addActions(new JTextField());
    private JPasswordField passwordPf = GUIUtils.addActions(
            new JPasswordField());
    private JTextField passwordTf = GUIUtils.addActions(
            new JTextField(passwordPf.getDocument(), null, 0));

    private JComboBox drivers;

    private JButton cancelBtn = new JButton();
    private JButton okBtn = new JButton();

    private JToggleButton showPswdBtn = new JToggleButton(
            new ShowPswdBtnAction());
    private JButton buildUrlBtn = new JButton(new BuildUrlBtnAction());

    /*
     *  Put here initialisation or even declaration of service it's not MVP or
     * MVC, so it must be correct in future!
     */

    private DriverService service;

    public ConnectionDialog(DriverService service){
        this.service = service;
        setModal(true);
        setTitle(i18n.getTitle());

        ActionListener al = new ActionListener() {
            @Override public void actionPerformed(ActionEvent e) {
                Action action = okBtn.getAction();
                if (action != null){
                    action.actionPerformed(e);
                } else {
                    for(ActionListener al : okBtn.getActionListeners()){
                        al.actionPerformed(e);
                    }
                }
            }
        };

        passwordPf.addActionListener(al);
        passwordTf.addActionListener(al);
        user.addActionListener(al);
        url.addActionListener(al);

        passwordTf.setVisible(false);
        drivers = new JComboBox(service.getSafetyAvailableDrivers().toArray());
        drivers.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                DriverDefenition item =
                        (DriverDefenition) drivers.getSelectedItem();
                if (item != null && item.getDefaultURL() != null){
                    url.setText(item.getDefaultURL());
                }
            }
        });
        if(drivers.getItemCount() > 0){
            drivers.setSelectedIndex(0);
        }

        setSize(passwordPf);
        setSize(passwordTf);
        setSize(user);
        setSize(url);

        JPanel contentPane = new JPanel(new BorderLayout());

        Box pane = Box.createVerticalBox();
        pane.add(GUIUtils.vBorder(getComponentInPanel(user, i18n.getUserName()),
                8, 4));
        pane.add(GUIUtils.vBorder(getComponentInPanel(toOne(passwordPf,
                passwordTf, showPswdBtn), i18n.getUserPassword()), 4, 4));
        pane.add(GUIUtils.vBorder(getComponentInPanel(toOne(url, buildUrlBtn),
                "URL"), 4, 4));

        pane.add(GUIUtils.vBorder(getComponentInPanel(drivers,
                i18n.getDbJDBC()), 4, 8));

        contentPane.add(GUIUtils.hBorder(pane), BorderLayout.NORTH);

        Box box = Box.createHorizontalBox();
        box.add(Box.createHorizontalGlue());
        box.add(GUIUtils.hBorder(okBtn));
        box.add(GUIUtils.hBorder(cancelBtn));

        Container content = getContentPane();
        content.add(contentPane);
        content.add(GUIUtils.vBorder(box), BorderLayout.SOUTH);

        resize();
    }

    public final void resize() {
        GUIUtils.setSize(this, 400);
        setLocationRelativeTo(null);
    }

    public JButton getCancelBtn() {
        return cancelBtn;
    }

    public JButton getOkBtn() {
        return okBtn;
    }

    public JTextField getPasswordTf() {
        return passwordTf;
    }

    public JTextField getUrl() {
        return url;
    }

    public JTextField getUser() {
        return user;
    }

    public JComboBox getDrivers() {
        return drivers;
    }

    abstract class SmallBtnAction extends AbstractAction {
        public SmallBtnAction(String name, String tooltipe) {
            this(i18n.getGUIShowPswdBtnText(),
                    ResourceHandle.getIcon(name + ".png", IconType.small),
                    tooltipe);
        }

        public SmallBtnAction(String name, Icon icon, String description) {
            super(name, icon);
            putValue(SHORT_DESCRIPTION, description);
        }
    }

    class ShowPswdBtnAction extends SmallBtnAction {

        public ShowPswdBtnAction() {
            super("showPswdBtn", i18n.getGUIShowPswdBtnTooltipe());
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() instanceof JToggleButton){
                JToggleButton button = (JToggleButton) e.getSource();
                if (button.isSelected()){
                    passwordPf.setVisible(false);
                    passwordTf.setVisible(true);
                } else {
                    passwordPf.setVisible(true);
                    passwordTf.setVisible(false);
                }
                ((JComponent)passwordPf.getParent()).revalidate();
            }
        }
    }

    class BuildUrlBtnAction extends SmallBtnAction {

        public BuildUrlBtnAction() {
            super("buildUrlBtn", null);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            final JDialog d = new JDialog(ConnectionDialog.this, i18n.getTitle());
            String[] parseURL = service.parseURL(url.getText());
            final JTextField n = new JTextField(parseURL[0]);
            final JTextField h = new JTextField(parseURL[1]);
            final JTextField p = new JTextField(parseURL[2]);
            final JTextField m = new JTextField(parseURL[3]);
            SmallBtnAction action = new SmallBtnAction("Ok", null) {
                @Override public void actionPerformed(ActionEvent e) {
                    url.setText(service.buildURL(m.getText(), h.getText(), p.getText(), n.getText()));
                    d.dispose();
                }
            };
            JButton button = new JButton(action);
            n.addActionListener(action);
            h.addActionListener(action);
            p.addActionListener(action);
            m.addActionListener(action);

            Box pane = Box.createVerticalBox();
            pane.add(GUIUtils.vBorder(getComponentInPanel(m, i18n.getDbClass()), 8, 4));
            pane.add(GUIUtils.vBorder(getComponentInPanel(h, i18n.getDbHost()), 4, 4));
            pane.add(GUIUtils.vBorder(getComponentInPanel(p, i18n.getDbPort()), 4, 4));
            pane.add(GUIUtils.vBorder(getComponentInPanel(n, i18n.getDbName()), 4, 8));

            Box box = Box.createHorizontalBox();
            box.add(Box.createHorizontalGlue());
            box.add(GUIUtils.hBorder(button));

            Container content = d.getContentPane();
            content.add(GUIUtils.hBorder(pane), BorderLayout.NORTH);
            content.add(GUIUtils.vBorder(box), BorderLayout.SOUTH);

            GUIUtils.setSize(d, 340);
            d.setLocationRelativeTo(null);
            d.setVisible(true);
        }
    }

    private JPanel getComponentInPanel(JComponent comp, String title){
        JPanel pane = new JPanel(new BorderLayout(8, 8));
        TitledBorder border = BorderFactory.createTitledBorder(new RoundEdgedBorder(), title);
        border.setTitleColor(Color.BLACK);
        pane.setBorder(BorderFactory.createTitledBorder(new RoundEdgedBorder(), title));
        pane.add(comp);
        return pane;
    }

    private JComponent toOne(JComponent... comps){
        JComponent pswdPane = Box.createVerticalBox();
        for (int i = 0; i < comps.length; i++) {
            if(i + 1 == comps.length){
                Box b = Box.createHorizontalBox();
                b.add(Box.createGlue());
                b.add(comps[i]);
                pswdPane.add(b);
            } else {
                pswdPane.add(comps[i]);
            }
        }
        return pswdPane;
    }

    Dimension setSize(JComponent comp){
        Dimension ps = comp.getPreferredSize();
        ps.width = comp.getMaximumSize().width;
        comp.setMaximumSize(ps);
        return ps;
    }
}
